<?php
/**
 * Created by PhpStorm.
 * User: yandian
 * Date: 17/3/2
 * Time: 17:51
 */

namespace app\common\util;


class ValueBag implements \ArrayAccess
{

    private $_source;

    public function __construct($source)
    {
        $this->_source = $source;
    }

    public static function wrap($source)
    {
        return new static($source);
    }

    public function __get($name)
    {
        // TODO: Implement __get() method.
        $found = 0;
        $rt = '';
        if (is_array($this->_source)) {
            if (isset($this->_source[$name])) {
                $found = 1;
                $rt = $this->_source[$name];
            }
        }
        if (is_object($this->_source)) {
            if (isset($this->_source->$name)) {
                $found = 1;
                $rt = $this->_source->$name;
            }
        }
        if (!$found) {
            if (strpos($name, '__')) {
                list($opkey, $opfield) = explode('__', $name);
                return self::getOptions($opkey, $this->__get($opfield));
            }
        }
        return $rt;
    }

    public static function getOptions($key = null, $key2 = null)
    {
        static $options = null;
        if (empty($options)) {
            $file = APP_PATH . 'common/data/options.php';
            if (file_exists($file)) {
                $options = include $file;
            }
        }
        if (is_null($key) || $key === '') {
            return $options;
        }
        if (is_null($key2)) {
            return !isset($options[$key]) ? '' : $options[$key];
        }
        if (!empty($options[$key]) && isset($options[$key][$key2])) {
            return $options[$key][$key2];
        }
        return '';
    }

    public function __set($name, $value)
    {
        // TODO: Implement __set() method.
        if (is_array($this->_source)) {
            $this->_source[$name] = $value;
        }
        if (is_object($this->_source)) {
            $this->_source->$name = $value;
        }
    }

    /**
     * Whether a offset exists
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
     * @param mixed $offset <p>
     * An offset to check for.
     * </p>
     * @return boolean true on success or false on failure.
     * </p>
     * <p>
     * The return value will be casted to boolean if non-boolean was returned.
     * @since 5.0.0
     */
    public function offsetExists($offset)
    {
        // TODO: Implement offsetExists() method.
        // TODO: Implement __set() method.
        if (is_array($this->_source)) {
            return array_key_exists($offset, $this->_source);
        }
        if (is_object($this->_source)) {
            return property_exists($this->_source, $offset);
        }
    }

    /**
     * Offset to retrieve
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
     * @param mixed $offset <p>
     * The offset to retrieve.
     * </p>
     * @return mixed Can return all value types.
     * @since 5.0.0
     */
    public function offsetGet($offset)
    {
        // TODO: Implement offsetGet() method.
        return $this->__get($offset);
    }

    /**
     * Offset to set
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
     * @param mixed $offset <p>
     * The offset to assign the value to.
     * </p>
     * @param mixed $value <p>
     * The value to set.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetSet($offset, $value)
    {
        // TODO: Implement offsetSet() method.
        $this->__set($offset, $value);
    }

    /**
     * Offset to unset
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
     * @param mixed $offset <p>
     * The offset to unset.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetUnset($offset)
    {
        // TODO: Implement offsetUnset() method.
        if (is_array($this->_source)) {
            unset($this->_source[$offset]);
        }
        if (is_object($this->_source)) {
            unset($this->_source->$offset);
        }
    }
}